package sjtu.rfid.rri.services.device;

import java.io.IOException;
import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.JAXBException;

import sjtu.rfid.rri.services.tag.TagModel;

/**
 * This interface defines the remote operations of device controlling.<br>
 * These methods are called not only from a single JVM, but also from Web
 * Services, RMI, etc.
 * 
 * @author jinghao
 * 
 */
@WebService
public interface DeviceService {

	public void loadReadersFromFile(String devicesFileURL) throws IOException,
			JAXBException;

	/**
	 * restart Device Server and clean all resources.
	 * 
	 */
	public void restartServer();

	/**
	 * restore Device Server from List of ReaderConfig, this will restart the
	 * Device Server.
	 * 
	 * @param readerConfigs
	 *            if pass null, the server will restart restoring with the state
	 *            before calling this function.
	 */
	public void restoreServer(List<ReaderConfig> readerConfigs);

	/**
	 * Create a new reader instance.<br>
	 * This method is designed to be only valid in the same JVM.
	 * 
	 * @param readerConfig
	 *            the configuration of the reader
	 * @return a new reader instance
	 * @throws DeviceDriverNotExistException
	 *             if there exists no such device driver.
	 * @throws DeviceException
	 *             if there exists some error when creating reader.
	 */
	public void createReader(
			@WebParam(name = "readerConfig") ReaderConfig readerConfig)
			throws DeviceDriverNotExistException, DeviceException;

	/**
	 * Destroy a created reader. Clients must use this method to destroy their
	 * created readers.<br>
	 * This method is designed to be only valid in the same JVM.
	 * 
	 * @param readerID
	 *            the reader's ID
	 * @throws NoSuchReaderException
	 *             if the readerID specified by client can't be found
	 */
	public void destroyReader(@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException;

	/**
	 * modify an existing reader specified by the readerID
	 * 
	 * @param readerID
	 *            the unique ID of a reader
	 * @param newReaderConfig
	 *            the new reader configuration information
	 * @throws NoSuchReaderIDException
	 *             if the readerID specified by client can't be found
	 * @throws DeviceDriverNotExistException
	 *             if there exists no such device driver.
	 * @throws DeviceException
	 *             if there exists some error when creating reader.
	 */
	public void modifyReader(String readerID, ReaderConfig newReaderConfig)
			throws NoSuchReaderException, DeviceDriverNotExistException,
			DeviceException;

	/**
	 * reload an existing reader specified by the readerID. This is equal to the
	 * combination of deleteReader and createReader.
	 * 
	 * @param readerID
	 *            the unique ID of a reader
	 * @throws NoSuchReaderException
	 *             if the readerID specified by client can't be found
	 * @throws DeviceDriverNotExistException
	 *             if there exists no such device driver.
	 * @throws DeviceException
	 *             if there exists some error when creating reader.
	 */
	public void reloadReader(String readerID) throws NoSuchReaderException,
			DeviceDriverNotExistException, DeviceException;

	/**
	 * reset (hardware) an existing reader specified by the readerID.
	 * 
	 * @param readerID
	 *            the unique ID of a reader
	 * @param readerInfo
	 *            the reader configuration information
	 * @throws NoSuchReaderException
	 *             if the readerID specified by client can't be found
	 */
	public void resetReader(String readerID) throws NoSuchReaderException;

	/**
	 * get the ReaderConfigs according to the ReadingStatus with this Device
	 * Server
	 * 
	 * @param readingStatus
	 *            the ReadingStatus, pass null to return all ReaderConfigs
	 * @return the ReaderConfigs according to the ReadingStatus with this Device
	 *         Server
	 */
	public List<ReaderConfig> getReaderConfigs(ReadingStatus readingStatus);

	/**
	 * Get the description of the out-queue associated with the specified
	 * reader.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @return the description of the out-queue associated with the specified
	 *         reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * @throws DeviceException
	 *             if the operation failed to complete
	 */
	public String getOutQueueDescription(
			@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException;

	/**
	 * Get the description of the in-queue associated with the specified reader.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @return the description of the in-queue associated with the specified
	 *         reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * @throws DeviceException
	 *             if the operation failed to complete
	 */
	public String getInQueueDescription(
			@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException;

	/** ****************************************************************** */
	/** ********** the operations of device reading controlling *********** */
	/** ****************************************************************** */

	/**
	 * Establish connection to reader and start reading data. It has no effect
	 * if the reading has been started. Put reading into ACTIVE status.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * @throws ReadingOperationException
	 *             if the operation of device reading control failed to
	 *             complete.
	 */
	public void startReading(@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException, ReadingOperationException;

	/**
	 * Pause the reader from receiving tags and it has no effect if reader is
	 * not active. Put reading into PAUSED status.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * @throws ReadingOperationException
	 *             if the operation of device reading control failed to
	 *             complete.
	 */
	public void pauseReading(@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException, ReadingOperationException;

	/**
	 * Activate the reader to receive tags again and it has no effect if reader
	 * is not paused. Put reader into ACTIVE status.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * @throws ReadingOperationException
	 *             if the operation of device reading control failed to
	 *             complete.
	 */
	public void resumeReading(@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException, ReadingOperationException;

	/**
	 * Close reader connection and stop reading data. It has no effect if
	 * reading has been stopped. Put reading into CLOSED status, and CLOSED
	 * status should jump into UNSTARTED status automatically.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * @throws ReadingOperationException
	 *             if the operation of device reading control failed to
	 *             complete.
	 */
	public void stopReading(@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException, ReadingOperationException;

	/**
	 * get the status of reading. Either UNSTARTED, ACTIVE , PAUSED or CLOSED.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @return the status of reading of the specified reader
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 */
	public ReadingStatus getReadingStatus(
			@WebParam(name = "readerID") String readerID)
			throws NoSuchReaderException;

	/**
	 * write the information specified by tagModel to the tag.
	 * 
	 * @param readerID
	 *            the ID of the reader
	 * @param operation
	 *            the operation to carry out
	 * @param tagModel
	 *            the tag contents
	 * @throws NoSuchReaderException
	 *             When a readerID specified by user can't be found
	 * 
	 */
	public void operateTag(@WebParam(name = "readerID") String readerID,
			Operation operation, TagModel tagModel)
			throws NoSuchReaderException;

}
